﻿using System.IO;

namespace Pittypat
{
    /// <summary>
    /// 表示用户登录的结果，由 <see cref="IAuthorityService.LoginAsync(string, string, string, IAsyncProgress)"/> 方法使用作为返回结果。
    /// </summary>
    /// <remarks>
    /// 登录结果返回用户令牌和用户信息，登录成功后属性 <see cref="User"/> 不能为 null，否则被视为登录失败。如果设置了用户的 LoginHomeUrl，则跳转到目标路径，否则停留在当前页面。
    /// </remarks>
    public sealed class LoginResult : Model
    {
        /// <summary>
        /// 表示匿名用户登录结果。这是一个只读字段。
        /// </summary>
        public static readonly LoginResult Anonymous = new LoginResult(Pittypat.User.Anonymous, "");

        /// <summary>
        /// 使用登录用户的用户信息和用户令牌初始化 LoginResult 的新实例。
        /// </summary>
        /// <param name="user">用户信息。</param>
        /// <param name="token">用户令牌。</param>
        public LoginResult(IUser user, string token)
        {
            this.User = user ?? Pittypat.User.Anonymous;
            this.Token = token ?? "";
        }

        /// <summary>
        /// 获取一个值，该值指示当前登录的结果是否代表了匿名用户。
        /// </summary>
        /// <remarks>
        /// 如果 User 为 null，或者 User.Id 没有值，或者 Token 为 null 或空字符串，则返回 true，否则返回 false。
        /// </remarks>
        public bool IsAnonymous
        {
            get
            {
                return this.User == null || !this.User.Id.HasValue || string.IsNullOrEmpty(this.Token);
            }
        }

        /// <summary>
        /// 获取登录用户的用户信息，其中包含 LoginHomeUrl。
        /// </summary>
        public IUser User { get; private set; }

        /// <summary>
        /// 获取登录用户的用户令牌。
        /// </summary>
        public string Token { get; internal set; }

        /// <summary>
        /// 将当前对象作为 JSON 字符串写入指定的文本流。
        /// </summary>
        /// <param name="writer">目标文本流。</param>
        /// <exception cref="global::System.ArgumentNullException">writer 是 null。</exception>
        public override void Write(TextWriter writer)
        {
            if (writer == null)
            {
                throw new global::System.ArgumentNullException("writer");
            }

            writer.Write("{\"user\":");
            if (this.User == null)
            {
                writer.Write("null");
            }
            else
            {
                this.User.Write(writer);
            }

            writer.Write(",\"token\":\"{0}\"}}", Json.Escape(this.Token));
        }
    }
}
